<?php
namespace Cyfy;

/**
 * Class for handling blocks
 *
 * Class which allows blocks to be dynamically reloaded and provides some other useful methods.
 *
 * @category cyfy
 * @author Dandelion <dandelion8888@gmail.com>
 * @version 0.1
 */ 
class Blocks extends Translatable
{
    /**
     * When we want a list of modules, hasRun is used for runonce method.
     * @var bool
     */
    static private $hasRun = false;
    
    /**
     * Cache of modules which have method 'blocks'
     * @var array
     */
    static private $modules = array();
    
    /**
     * Triggers showing blocks, which wouldn't be normally shown. Eg. <em>login form</em> when user is logged in.
     * @var bool
     */
    static public $forcedShow = false;
  
    
    /**
     * Returns a block defined by parameters
     *
     * Calls a method <em>$module :: blocks($block)</em> and returns its contents.
     * If method is not found, returns FALSE.
     *
     * @param string Module name
     * @param string Block name
     * @return mixed HTML content if blocks was successfuly loaded, FALSE otherwise.
     */
    static public function getBlock($module, $block)
    {
        if(!file_exists("Cyfy/Modules/$module/Module.php"))
        {
            return false;
        }
        
        $class = "\Cyfy\Modules\\" .  $module. "\\Module";
        if(method_exists($class, "blocks"))
        {
             // get contents
            $contents = $class :: blocks($block);
            
            // extra            
            $extra = "";
            // show id when editing template
            if(self :: $forcedShow)
            {
                $extra = "<input type=\"hidden\" class=\"templateModuleID\" value=\"{$module}\" /><input type=\"hidden\" class=\"templateBlockID\" value=\"{$block}\" />";
            }
            
            // if no text, don't show any DIV element around
            if($contents)
            {
                $contents = "<div class=\"block {$module}__{$block}\">" . $contents . "{$extra}</div>";
            }
            
            return $contents;
        }
        
        // if method doesn't exist
        return false;
    }
    
    /**
     * Updates a block id / delete block;
     *
     * When a block id change, you must run this method.
     * If old name empty or not set, deletes all modules for the block.
     * If new name empty or not set, deletes the block.
     *
     * @param string Module name
     * @param string Old block name
     * @param string New block name
     * @return bool
     */
    static public function updateBlock($module, $oldName = '', $newName = '')
    {
        if($newName == '')
        {
            $query = array('DELETE FROM [:cyfy:Templates-blocks] WHERE [module] = %s ', $module);
            
            // if oldname set - delete just a block;
            if($oldName != '')
            {
                $query[] = ' AND [block] = %s ';
                $query[] = $oldName;
            }
            
            return \dibi :: query($query);            
        }
        
        // updating
        return \dibi :: query('UPDATE [:cyfy:Templates-blocks] SET [block] = %s ', $newName, 'WHERE [module] = %s ', $module, ' AND [block] = %s', $oldName);
    }
  
    /**
     * Returns list of blocks of Module
     *
     * List of blocks of a Module separated by newline.
     * If no blocks are found, returns false.
     *
     * @param string Module name
     * @return array
     */
    static public function blocksListClass($module)
    {
        $class = "\Cyfy\Modules\\" . $module . "\Module";
        
        if(!file_exists(classToPath($class) . ".php")) return false;
        if(!method_exists($class, "blocks")) return false;
            
        $ids = "";
        $names = "";
        foreach($class :: blocks() as $id => $name)
        {
            $ids .= $id . "\n";
            $names .= $name . "\n";
        }
        return array("ids" => $ids, "names" => $names);
    }
  
    /**
     * Handles depedencies.
     *
     * Adds a JS file into header and loads modules.
     * This method can be ran only once. 
     */
    static function runonce()
    {
        if(self :: $hasRun){
            return;
        }
        self :: $hasRun = true;
        foreach(\Cyfy\Modules :: getEnabled() as $module)
        {
            $class = "\Cyfy\Modules\\" . $module . "\Module";
            if(file_exists(classToPath($class) . ".php"))
            {
                if(method_exists($class, "blocks"))
                {
                    self :: $modules[] = $module;  
                }
            }
        }	
    }
  
    /**
     * Returns two SELECT elements.
     *
     * Returns two elements SELECT, one for modules, the other for blocks of the selected module.
     * The parameter specifies a JS code to be called when block is chosen. You can use these variables in the code:
     * <ul>
     * <li><em>module</em> = module name (actually class name)</li>
     * <li><em>block</em> = id of the block</li>
     * <li><em>name</em> = title of the block</li>
     * </ul>
     * Example of $onSelect contents:
     * <code>
     * alert('You have selected a block titled ' + name);
     * </code>
     *
     * @param string Part of JS code, which can be used when a block is chosen.
     * @param string HTML tag, in which is the caption covered.
     * @return mixed Two select elements and caption in DIV element.
     */
    static function select($onSelect="", $tag="p")
    {
        self :: runonce(); 
        
        if(count(self::$modules)==0){
            return false;
        }

        $options = "\n  <option value=\"\">" . self :: t(20) . "</option>\n";
        
        $sortedModules = self :: $modules;
        asort($sortedModules);
        
        foreach($sortedModules as $module)
        {
            $options .= "  <option value=\"{$module}\">" . $module . "</option>\n";
        }   

        $output = "<div class=\"blocks-select\">\n\n";
        $output .= "<{$tag} class=\"blocks-select-label\"><span class=\"label\">" . self :: t(10) . ":</span></{$tag}>\n";
        $output .= "<select name=\"blocks-modules\" class=\"blocks-modules\">" . $options . "</select>\n";
        $output .= "<select name=\"blocks-blocks\" class=\"blocks-blocks\" onchange=\"if($(this).val()){ var module = $(this).prev().val(); var block = $(this).val(); var name = this.options[this.selectedIndex].text; {$onSelect};}\"></select>\n";
        $output .= "</div>\n\n";
        return $output;
    }
}



